<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>中国象棋</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            font-family: 'Microsoft YaHei', sans-serif;
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
            min-height: 100vh;
            margin: 0;
            padding: 20px;
            color: #fff;
        }
        
        .game-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            background: rgba(139, 69, 19, 0.8);
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
            max-width: 800px;
            width: 100%;
        }
        
        h1 {
            font-size: 2.8rem;
            margin-bottom: 10px;
            text-shadow: 3px 3px 5px rgba(0, 0, 0, 0.7);
            color: #FFD700;
            letter-spacing: 3px;
        }
        
        .subtitle {
            font-size: 1.2rem;
            margin-bottom: 20px;
            color: #FFD700;
        }
        
        .board-container {
            position: relative;
            margin: 20px 0;
        }
        
        canvas {
            background: #e8c78e;
            border: 4px solid #5d2906;
            border-radius: 5px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.6);
            cursor: pointer;
        }
        
        .info-panel {
            display: flex;
            justify-content: space-between;
            width: 100%;
            max-width: 600px;
            background: rgba(93, 41, 6, 0.8);
            padding: 15px;
            border-radius: 8px;
            margin: 15px 0;
        }
        
        .player-info {
            text-align: center;
            padding: 10px;
            border-radius: 5px;
            min-width: 120px;
        }
        
        .red-player {
            background: rgba(178, 34, 34, 0.7);
            border: 2px solid #FF0000;
        }
        
        .black-player {
            background: rgba(0, 0, 0, 0.7);
            border: 2px solid #333;
        }
        
        .current-turn {
            box-shadow: 0 0 15px 5px #FFD700;
            transform: scale(1.05);
        }
        
        .player-name {
            font-size: 1.3rem;
            font-weight: bold;
            margin-bottom: 8px;
        }
        
        .controls {
            display: flex;
            gap: 15px;
            margin-top: 15px;
        }
        
        button {
            padding: 12px 25px;
            font-size: 1.1rem;
            background: linear-gradient(to bottom, #8B4513, #5d2906);
            color: #FFD700;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: all 0.3s;
            font-weight: bold;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
        }
        
        button:hover {
            background: linear-gradient(to bottom, #A0522D, #6d3911);
            transform: translateY(-2px);
            box-shadow: 0 6px 8px rgba(0, 0, 0, 0.4);
        }
        
        button:active {
            transform: translateY(1px);
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
        }
        
        .rules {
            background: rgba(0, 0, 0, 0.6);
            padding: 15px;
            border-radius: 8px;
            margin-top: 20px;
            max-width: 600px;
            font-size: 0.9rem;
            line-height: 1.5;
        }
        
        .rules h3 {
            color: #FFD700;
            margin-top: 0;
        }
        
        .highlight {
            background-color: rgba(255, 215, 0, 0.2);
            border-radius: 3px;
            padding: 0 5px;
        }
        
        .status {
            font-size: 1.3rem;
            font-weight: bold;
            margin: 15px 0;
            min-height: 30px;
            color: #FFD700;
            text-align: center;
            text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>中国象棋</h1>
        <div class="subtitle">楚河汉界 · 将帅之争</div>
        
        <div class="status" id="gameStatus">红方先行</div>
        
        <div class="board-container">
            <canvas id="chessBoard" width="500" height="555"></canvas>
        </div>
        
        <div class="info-panel">
            <div class="player-info red-player current-turn" id="redPlayer">
                <div class="player-name">红方</div>
                <div>将：帅 × 1</div>
                <div>士：仕 × 2</div>
                <div>象：相 × 2</div>
                <div>车：车 × 2</div>
                <div>马：马 × 2</div>
                <div>炮：炮 × 2</div>
                <div>兵：兵 × 5</div>
            </div>
            
            <div class="player-info black-player" id="blackPlayer">
                <div class="player-name">黑方</div>
                <div>将：将 × 1</div>
                <div>士：士 × 2</div>
                <div>象：象 × 2</div>
                <div>车：车 × 2</div>
                <div>马：马 × 2</div>
                <div>炮：炮 × 2</div>
                <div>兵：卒 × 5</div>
            </div>
        </div>
        
        <div class="controls">
            <button id="newGame">新游戏</button>
            <button id="undoMove">悔棋</button>
            <button id="toggleSound">音效: 开</button>
        </div>
        
        <div class="rules">
            <h3>游戏规则</h3>
            <p>· <span class="highlight">帅/将</span>：只能在九宫格内移动，每次一步</p>
            <p>· <span class="highlight">仕/士</span>：只能在九宫格内沿斜线移动</p>
            <p>· <span class="highlight">相/象</span>：走"田"字，不能过河，田字中心有子不能走</p>
            <p>· <span class="highlight">马</span>：走"日"字，蹩马腿时不能走</p>
            <p>· <span class="highlight">车</span>：直线移动，距离不限</p>
            <p>· <span class="highlight">炮</span>：移动同车，吃子需隔一子</p>
            <p>· <span class="highlight">兵/卒</span>：过河前向前一步，过河后可左右移动</p>
            <p>· <span class="highlight">胜负</span>：将死对方将/帅者获胜，将帅不能直接照面</p>
        </div>
    </div>

    <script>
        // 游戏主要类
        class XiangqiGame {
            constructor(canvasId) {
                this.canvas = document.getElementById(canvasId);
                this.ctx = this.canvas.getContext('2d');
                this.pieces = [];
                this.selectedPiece = null;
                this.currentPlayer = 'red'; // 'red' 或 'black'
                this.gameOver = false;
                this.moveHistory = [];
                this.soundEnabled = true;
                
                // 设置棋盘尺寸
                this.boardWidth = 9;
                this.boardHeight = 10;
                this.cellSize = Math.min(this.canvas.width / this.boardWidth, this.canvas.height / this.boardHeight);
                this.pieceRadius = this.cellSize * 0.4;
                
                // 初始化游戏
                this.initializePieces();
                this.drawBoard();
                this.drawPieces();
                
                // 事件监听
                this.canvas.addEventListener('click', this.handleClick.bind(this));
                this.canvas.addEventListener('mousedown', this.handleMouseDown.bind(this));
                this.canvas.addEventListener('mousemove', this.handleMouseMove.bind(this));
                this.canvas.addEventListener('mouseup', this.handleMouseUp.bind(this));
                
                // 按钮事件
                document.getElementById('newGame').addEventListener('click', () => this.resetGame());
                document.getElementById('undoMove').addEventListener('click', () => this.undoMove());
                document.getElementById('toggleSound').addEventListener('click', () => this.toggleSound());
                
                // 初始化拖拽状态
                this.dragging = false;
                this.dragPiece = null;
                this.dragOffsetX = 0;
                this.dragOffsetY = 0;
            }
            
            // 初始化棋子
            initializePieces() {
                // 黑方棋子（上方）
                this.pieces = [
                    // 车
                    { type: 'rook', color: 'black', x: 0, y: 0 },
                    { type: 'rook', color: 'black', x: 8, y: 0 },
                    
                    // 马
                    { type: 'knight', color: 'black', x: 1, y: 0 },
                    { type: 'knight', color: 'black', x: 7, y: 0 },
                    
                    // 象
                    { type: 'bishop', color: 'black', x: 2, y: 0 },
                    { type: 'bishop', color: 'black', x: 6, y: 0 },
                    
                    // 士
                    { type: 'advisor', color: 'black', x: 3, y: 0 },
                    { type: 'advisor', color: 'black', x: 5, y: 0 },
                    
                    // 将
                    { type: 'king', color: 'black', x: 4, y: 0 },
                    
                    // 炮
                    { type: 'cannon', color: 'black', x: 1, y: 2 },
                    { type: 'cannon', color: 'black', x: 7, y: 2 },
                    
                    // 卒
                    { type: 'pawn', color: 'black', x: 0, y: 3 },
                    { type: 'pawn', color: 'black', x: 2, y: 3 },
                    { type: 'pawn', color: 'black', x: 4, y: 3 },
                    { type: 'pawn', color: 'black', x: 6, y: 3 },
                    { type: 'pawn', color: 'black', x: 8, y: 3 },
                    
                    // 红方棋子（下方）
                    // 车
                    { type: 'rook', color: 'red', x: 0, y: 9 },
                    { type: 'rook', color: 'red', x: 8, y: 9 },
                    
                    // 马
                    { type: 'knight', color: 'red', x: 1, y: 9 },
                    { type: 'knight', color: 'red', x: 7, y: 9 },
                    
                    // 相
                    { type: 'bishop', color: 'red', x: 2, y: 9 },
                    { type: 'bishop', color: 'red', x: 6, y: 9 },
                    
                    // 仕
                    { type: 'advisor', color: 'red', x: 3, y: 9 },
                    { type: 'advisor', color: 'red', x: 5, y: 9 },
                    
                    // 帅
                    { type: 'king', color: 'red', x: 4, y: 9 },
                    
                    // 炮
                    { type: 'cannon', color: 'red', x: 1, y: 7 },
                    { type: 'cannon', color: 'red', x: 7, y: 7 },
                    
                    // 兵
                    { type: 'pawn', color: 'red', x: 0, y: 6 },
                    { type: 'pawn', color: 'red', x: 2, y: 6 },
                    { type: 'pawn', color: 'red', x: 4, y: 6 },
                    { type: 'pawn', color: 'red', x: 6, y: 6 },
                    { type: 'pawn', color: 'red', x: 8, y: 6 }
                ];
            }
            
            // 绘制棋盘
            drawBoard() {
                const ctx = this.ctx;
                const cellSize = this.cellSize;
                const width = this.boardWidth;
                const height = this.boardHeight;
                
                ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
                
                // 绘制棋盘背景
                ctx.fillStyle = '#e8c78e';
                ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
                
                // 绘制网格线
                ctx.strokeStyle = '#000';
                ctx.lineWidth = 1;
                
                // 绘制横线
                for (let i = 0; i <= height; i++) {
                    ctx.beginPath();
                    ctx.moveTo(cellSize / 2, i * cellSize + cellSize / 2);
                    ctx.lineTo((width - 0.5) * cellSize, i * cellSize + cellSize / 2);
                    ctx.stroke();
                }
                
                // 绘制竖线
                for (let i = 0; i <= width; i++) {
                    if (i === 0 || i === width) {
                        ctx.beginPath();
                        ctx.moveTo(i * cellSize + cellSize / 2, cellSize / 2);
                        ctx.lineTo(i * cellSize + cellSize / 2, (height - 0.5) * cellSize);
                        ctx.stroke();
                    } else {
                        // 上半部分
                        ctx.beginPath();
                        ctx.moveTo(i * cellSize + cellSize / 2, cellSize / 2);
                        ctx.lineTo(i * cellSize + cellSize / 2, (height / 2 - 0.5) * cellSize);
                        ctx.stroke();
                        
                        // 下半部分
                        ctx.beginPath();
                        ctx.moveTo(i * cellSize + cellSize / 2, (height / 2 + 0.5) * cellSize);
                        ctx.lineTo(i * cellSize + cellSize / 2, (height - 0.5) * cellSize);
                        ctx.stroke();
                    }
                }
                
                // 绘制九宫格
                // 上方九宫格
                ctx.beginPath();
                ctx.moveTo(3 * cellSize + cellSize / 2, 0 * cellSize + cellSize / 2);
                ctx.lineTo(5 * cellSize + cellSize / 2, 2 * cellSize + cellSize / 2);
                ctx.moveTo(5 * cellSize + cellSize / 2, 0 * cellSize + cellSize / 2);
                ctx.lineTo(3 * cellSize + cellSize / 2, 2 * cellSize + cellSize / 2);
                ctx.stroke();
                
                // 下方九宫格
                ctx.beginPath();
                ctx.moveTo(3 * cellSize + cellSize / 2, 7 * cellSize + cellSize / 2);
                ctx.lineTo(5 * cellSize + cellSize / 2, 9 * cellSize + cellSize / 2);
                ctx.moveTo(5 * cellSize + cellSize / 2, 7 * cellSize + cellSize / 2);
                ctx.lineTo(3 * cellSize + cellSize / 2, 9 * cellSize + cellSize / 2);
                ctx.stroke();
                
                // 绘制"楚河汉界"
                ctx.font = 'bold 40px KaiTi, STKaiti, serif';
                ctx.fillStyle = '#8B4513';
                ctx.textAlign = 'center';
                ctx.fillText('楚 河', 2.5 * cellSize, 4.8 * cellSize);
                ctx.fillText('汉 界', 6.5 * cellSize, 4.8 * cellSize);
            }
            
            // 绘制棋子
            drawPieces() {
                const ctx = this.ctx;
                const cellSize = this.cellSize;
                
                this.pieces.forEach(piece => {
                    const x = piece.x * cellSize + cellSize / 2;
                    const y = piece.y * cellSize + cellSize / 2;
                    
                    // 绘制棋子背景
                    ctx.beginPath();
                    ctx.arc(x, y, this.pieceRadius, 0, Math.PI * 2);
                    ctx.fillStyle = piece.color === 'red' ? '#F5F5DC' : '#000';
                    ctx.fill();
                    ctx.strokeStyle = piece === this.selectedPiece ? '#FFD700' : '#8B4513';
                    ctx.lineWidth = piece === this.selectedPiece ? 3 : 2;
                    ctx.stroke();
                    
                    // 绘制棋子文字
                    ctx.font = `bold ${this.pieceRadius * 1.2}px KaiTi, STKaiti, serif`;
                    ctx.fillStyle = piece.color === 'red' ? '#CD0000' : '#FFF';
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    
                    // 棋子名称映射
                    const pieceNames = {
                        'rook': { red: '车', black: '车' },
                        'knight': { red: '马', black: '马' },
                        'bishop': { red: '相', black: '象' },
                        'advisor': { red: '仕', black: '士' },
                        'king': { red: '帅', black: '将' },
                        'cannon': { red: '炮', black: '炮' },
                        'pawn': { red: '兵', black: '卒' }
                    };
                    
                    ctx.fillText(pieceNames[piece.type][piece.color], x, y);
                });
            }
            
            // 处理点击事件
            handleClick(event) {
                if (this.gameOver) return;
                
                const rect = this.canvas.getBoundingClientRect();
                const x = event.clientX - rect.left;
                const y = event.clientY - rect.top;
                
                const cellX = Math.floor(x / this.cellSize);
                const cellY = Math.floor(y / this.cellSize);
                
                // 检查是否点击了棋子
                const clickedPiece = this.getPieceAt(cellX, cellY);
                
                if (this.selectedPiece) {
                    // 尝试移动棋子
                    if (clickedPiece && clickedPiece.color === this.selectedPiece.color) {
                        // 选择另一个己方棋子
                        this.selectedPiece = clickedPiece;
                    } else {
                        // 尝试移动选中棋子到目标位置
                        this.movePiece(this.selectedPiece, cellX, cellY);
                    }
                } else if (clickedPiece && clickedPiece.color === this.currentPlayer) {
                    // 选中己方棋子
                    this.selectedPiece = clickedPiece;
                }
                
                this.drawBoard();
                this.drawPieces();
            }
            
            // 处理鼠标按下事件（开始拖拽）
            handleMouseDown(event) {
                if (this.gameOver) return;
                
                const rect = this.canvas.getBoundingClientRect();
                const x = event.clientX - rect.left;
                const y = event.clientY - rect.top;
                
                const cellX = Math.floor(x / this.cellSize);
                const cellY = Math.floor(y / this.cellSize);
                
                const clickedPiece = this.getPieceAt(cellX, cellY);
                
                if (clickedPiece && clickedPiece.color === this.currentPlayer) {
                    this.dragging = true;
                    this.dragPiece = clickedPiece;
                    this.dragOffsetX = x - (clickedPiece.x * this.cellSize + this.cellSize / 2);
                    this.dragOffsetY = y - (clickedPiece.y * this.cellSize + this.cellSize / 2);
                    this.selectedPiece = clickedPiece;
                    this.drawBoard();
                    this.drawPieces();
                }
            }
            
            // 处理鼠标移动事件（拖拽中）
            handleMouseMove(event) {
                if (!this.dragging) return;
                
                const rect = this.canvas.getBoundingClientRect();
                const x = event.clientX - rect.left;
                const y = event.clientY - rect.top;
                
                this.drawBoard();
                this.drawPieces();
                
                // 绘制拖拽中的棋子
                if (this.dragPiece) {
                    const ctx = this.ctx;
                    const dragX = x - this.dragOffsetX;
                    const dragY = y - this.dragOffsetY;
                    
                    ctx.beginPath();
                    ctx.arc(dragX, dragY, this.pieceRadius, 0, Math.PI * 2);
                    ctx.fillStyle = this.dragPiece.color === 'red' ? '#F5F5DC' : '#000';
                    ctx.fill();
                    ctx.strokeStyle = '#FFD700';
                    ctx.lineWidth = 3;
                    ctx.stroke();
                    
                    // 绘制棋子文字
                    ctx.font = `bold ${this.pieceRadius * 1.2}px KaiTi, STKaiti, serif`;
                    ctx.fillStyle = this.dragPiece.color === 'red' ? '#CD0000' : '#FFF';
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'middle';
                    
                    const pieceNames = {
                        'rook': { red: '车', black: '车' },
                        'knight': { red: '马', black: '马' },
                        'bishop': { red: '相', black: '象' },
                        'advisor': { red: '仕', black: '士' },
                        'king': { red: '帅', black: '将' },
                        'cannon': { red: '炮', black: '炮' },
                        'pawn': { red: '兵', black: '卒' }
                    };
                    
                    ctx.fillText(pieceNames[this.dragPiece.type][this.dragPiece.color], dragX, dragY);
                }
            }
            
            // 处理鼠标释放事件（结束拖拽）
            handleMouseUp(event) {
                if (!this.dragging) return;
                
                this.dragging = false;
                
                const rect = this.canvas.getBoundingClientRect();
                const x = event.clientX - rect.left;
                const y = event.clientY - rect.top;
                
                const targetX = Math.floor(x / this.cellSize);
                const targetY = Math.floor(y / this.cellSize);
                
                if (this.dragPiece) {
                    this.movePiece(this.dragPiece, targetX, targetY);
                }
                
                this.dragPiece = null;
                this.drawBoard();
                this.drawPieces();
            }
            
            // 获取指定位置的棋子
            getPieceAt(x, y) {
                return this.pieces.find(piece => piece.x === x && piece.y === y);
            }
            
            // 移动棋子
            movePiece(piece, targetX, targetY) {
                // 保存移动历史用于悔棋
                this.moveHistory.push({
                    piece: {...piece},
                    targetX,
                    targetY,
                    capturedPiece: this.getPieceAt(targetX, targetY)
                });
                
                // 检查目标位置是否有对方棋子
                const targetPiece = this.getPieceAt(targetX, targetY);
                if (targetPiece && targetPiece.color !== piece.color) {
                    // 移除被吃掉的棋子
                    this.pieces = this.pieces.filter(p => p !== targetPiece);
                    
                    // 检查是否吃掉将帅
                    if (targetPiece.type === 'king') {
                        this.gameOver = true;
                        const winner = piece.color === 'red' ? '红方' : '黑方';
                        setTimeout(() => {
                            alert(`${winner}获胜！${winner === '红方' ? '黑方' : '红方'}的将帅被吃掉`);
                        }, 100);
                    }
                }
                
                // 移动棋子
                piece.x = targetX;
                piece.y = targetY;
                
                // 切换玩家
                this.currentPlayer = this.currentPlayer === 'red' ? 'black' : 'red';
                this.selectedPiece = null;
                
                // 更新状态显示
                this.updateStatus();
                
                // 播放音效
                if (this.soundEnabled) {
                    this.playMoveSound();
                }
            }
            
            // 更新游戏状态显示
            updateStatus() {
                const statusElement = document.getElementById('gameStatus');
                const redPlayer = document.getElementById('redPlayer');
                const blackPlayer = document.getElementById('blackPlayer');
                
                if (this.gameOver) {
                    statusElement.textContent = '游戏结束';
                } else {
                    statusElement.textContent = `${this.currentPlayer === 'red' ? '红方' : '黑方'}走棋`;
                }
                
                // 更新当前玩家高亮
                if (this.currentPlayer === 'red') {
                    redPlayer.classList.add('current-turn');
                    blackPlayer.classList.remove('current-turn');
                } else {
                    redPlayer.classList.remove('current-turn');
                    blackPlayer.classList.add('current-turn');
                }
            }
            
            // 播放移动音效
            playMoveSound() {
                // 在实际应用中，这里可以播放音效文件
                // 此示例仅使用控制台输出模拟
                console.log("播放移动音效");
            }
            
            // 重新开始游戏
            resetGame() {
                this.initializePieces();
                this.selectedPiece = null;
                this.currentPlayer = 'red';
                this.gameOver = false;
                this.moveHistory = [];
                this.drawBoard();
                this.drawPieces();
                this.updateStatus();
                
                // 重置玩家高亮
                const redPlayer = document.getElementById('redPlayer');
                const blackPlayer = document.getElementById('blackPlayer');
                redPlayer.classList.add('current-turn');
                blackPlayer.classList.remove('current-turn');
            }
            
            // 悔棋
            undoMove() {
                if (this.moveHistory.length === 0 || this.gameOver) return;
                
                const lastMove = this.moveHistory.pop();
                
                // 恢复棋子位置
                lastMove.piece.x = lastMove.piece.x;
                lastMove.piece.y = lastMove.piece.y;
                
                // 恢复被吃掉的棋子
                if (lastMove.capturedPiece) {
                    this.pieces.push(lastMove.capturedPiece);
                }
                
                // 切换回上一个玩家
                this.currentPlayer = this.currentPlayer === 'red' ? 'black' : 'red';
                this.gameOver = false;
                
                this.drawBoard();
                this.drawPieces();
                this.updateStatus();
            }
            
            // 切换音效
            toggleSound() {
                this.soundEnabled = !this.soundEnabled;
                const button = document.getElementById('toggleSound');
                button.textContent = `音效: ${this.soundEnabled ? '开' : '关'}`;
            }
        }
        
        // 页面加载完成后初始化游戏
        window.onload = function() {
            const game = new XiangqiGame('chessBoard');
        };
    </script>
</body>
</html>